package com.sparrow.common.util;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class IpUtil {

    /**
     * 判断某个 IP 是否在 CIDR 范围内,CIDR（Classless Inter-Domain Routing） 是一种表示 IP 地址范围的标准方式，CIDR 表示一个IP网段
     * CIDR格式：IP地址/掩码位数
     * IPv4 是 32 位的地址，例子192.168.1.0/24 ，，，/24表示前24为2为网络地址，后8位为主机地址 2的8次幂 = 256个ip,范围从 192.168.1.0 到 192.168.1.255
     *
     * @param ip     要判断的 IP，如 "192.168.1.42"
     * @param cidr   CIDR 表达式，如 "192.168.1.0/24"
     * @return       true 表示在范围内，false 表示不在
     */
    public static boolean isInRange(String ip, String cidr) {
        try {
            String[] parts = cidr.split("/");
            String cidrIp = parts[0];
            int prefixLength = Integer.parseInt(parts[1]);

            int ipAddr = toInt(InetAddress.getByName(ip));
            int cidrAddr = toInt(InetAddress.getByName(cidrIp));
            //相当于抹去主机部分 只保留网络部分作用
            //以下代码等同于 int mask = (int)(0xFFFFFFFFL << (32 - prefixLength));
            int mask = -1 << (32 - prefixLength);
            return (ipAddr & mask) == (cidrAddr & mask);
        } catch (UnknownHostException | NumberFormatException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 把 InetAddress 转为 int
    private static int toInt(InetAddress inetAddress) {
        byte[] bytes = inetAddress.getAddress();
        int result = 0;
        for (byte b : bytes) {
            result = (result << 8) | (b & 0xFF);
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(IpUtil.isInRange("192.168.1.42", "192.168.1.0/24")); // true
        System.out.println(IpUtil.isInRange("192.168.2.42", "192.168.1.0/24")); // false
        System.out.println(IpUtil.isInRange("10.0.5.123", "10.0.0.0/8"));       // true
        System.out.println(IpUtil.isInRange("172.16.0.1", "192.168.0.0/16"));   // false
    }
}